/*
 * sqlBuider.js v0.0.1
 * (c) 2018 wangjunxiao
 * Released under the MIT License.
 * 
 * 构造sql语句, 拒绝拼接 
 * 
 */

function SqlUtil() {

	var me = this;
	/**
	 * 构建sql 
	 * @param {string} sql 
	 * @param {array} params 参数数组
	 * @return {object} 返回 {"state": false, "msg":"错我"} 或者 {"state": true, "sql": sql}
	 */
	this.buildSql = function (sql, params) {
		var ret = sql;
		if (params) {
			for (var i = 0; i < params.length; ++i) {
				var para = params[i];

				//安全检查
				if (typeof para == 'undefined') {
					return {
						"state": false,
						"msg": '第' + i + "个参数是undefined"
					}
				}
				if (typeof para == 'string') {
					if (para) para = "'" + para + "'";
					else para = 'null';
				}
				sql = sql.replace("?", para)
				if (sql == ret) {
					return {
						"state": false,
						"msg": '参数个数多了'
					}
				}
				ret = sql;
			}

			if (/\?/.test(sql)) return {
				"state": false,
				"msg": '参数个数少了'
			}
		}
		return {
			"state": true,
			"sql": ret
		}
	}


	this.getObjectClass = function (obj) {
		if (obj && obj.constructor && obj.constructor.toString()) {
			/*
			 * for browsers which have name property in the constructor
			 * of the object,such as chrome 
			 */
			if (obj.constructor.name) {
				return obj.constructor.name.toLowerCase();
			}
			var str = obj.constructor.toString();
			/*
			 * executed if the return of object.constructor.toString() is 
			 * "[object objectClass]"
			 */
			if (str.charAt(0) == '[') {
				var arr = str.match(/\[\w+\s*(\w+)\]/);
			} else {
				/*
				 * executed if the return of object.constructor.toString() is 
				 * "function objectClass () {}"
				 * for IE Firefox
				 */
				var arr = str.match(/function\s*(\w+)/);
			}
			if (arr && arr.length == 2) {
				return arr[1].toLowerCase();
			}
		}
		return undefined;
	}

	function _buildInsertSql(obj, selectived) {
		if (typeof obj != "object") {
			return null;
		}

		var className = me.getObjectClass(obj);
		if (className == undefined) {
			return null;
		}

		var columnNames = [];
		var columnValues = [];
		for (var propertyName in obj) {
			var value = obj[propertyName]
			if((typeof value) == "function") continue;
			if (selectived) {
				if (value != undefined && value != null) {
					columnNames.push(propertyName)
					columnValues.push(obj[propertyName])
				}
			} else {
				columnNames.push(propertyName)
				columnValues.push(obj[propertyName])
			}

		}

		var sql = "insert into " + className + "("

		for (var i = 0; i < columnNames.length - 1; ++i) {
			sql += columnNames[i] + ",";
		}
		sql += columnNames[i] + ") values("

		for (var i = 0; i < columnNames.length - 1; ++i) {
			sql += "?, "
		}
		sql += "?)"


		var result = me.buildSql(sql, columnValues)
		if (result.state) {
			return result.sql;
		}
		return null;
	}

	this.buildInsertSql = function (obj) {
		return _buildInsertSql(obj, false)
	}

	this.buildInsertSelectiveSql = function (obj) {
		return _buildInsertSql(obj, true)
	}

	/**
	 * 创建查询语句 
	 * @param {string} tableName  要查询的表名
	 * @param {array} columnNames 要查询的列名，数组类型 [name, age]
	 * @param {string} whereSql where语句， 可不传
	 */
	this.buildSelectSql = function(tableName, columnNames, whereSql) {
		if(!tableName) {
			console.log("表名称不能为空")
			return null;
		}

		if(!columnNames || columnNames.length == 0)  {
			console.log("查询的字段不能为空")
			return null;
		}

		var sql = "select "	
		for(var i = 0; i < columnNames.length - 1; ++i) {
			sql += columnNames[i] + ","
		}
		sql += columnNames[columnNames.length - 1] + " ";

		sql += "from " + tableName;

		if(whereSql) {
			sql += " " + whereSql;
		 }
		 
		 return sql;
	}
	
}



	// var sqlBuilder = new SqlUtil();
	// var sql = sqlBuilder.buildSelectSql("organization", ["org_name", "org_id"]);
	// console.log(sql)

	// var whereSql = sqlBuilder.buildSql("where id = ? and name  = ?", [1, "wjx"]).sql;
	// console.log(whereSql)
	// var sql = sqlBuilder.buildSelectSql("organization", ["org_name", "org_id"], whereSql);
	// console.log(sql)


// orm 功能测试

(function () {
	function Person() {
		this.name = "wjx";
		this.age = 20;
		this.gender = 1;

		this.getName = function () {
			return this.name
		};
		this.getAge = function () {
			return this.age
		};
		this.getGender = function () {
			return this.gender
		};

		var me = this;
		this.toString = function () {
			return me.getName() + ", " + me.getAge() + ", " + me.getGender();
		}

	}
	var sqlBuilder = new SqlUtil();

	var person = new Person()
	console.log(person.toString())

	var sql = sqlBuilder.buildInsertSql(person)
	console.log(sql)

	sql = sqlBuilder.buildInsertSelectiveSql(person)
	console.log(sql)

	person.age = null;
	var sql = sqlBuilder.buildInsertSelectiveSql(person)
	console.log(sql)
})

// (function() {
// 	console.log("abc")
// 	// var db = new SqlUtil();
// 	// //少参数
// 	// var arr = db.buildSql('update user set name = ?, age = ?', ['wjx'])
// 	// console.log(JSON.stringify(arr))
// 	// //多参数
// 	// var arr = db.buildSql('update user set name = ?, age = ?', ['wjx', 'wjx', 'wjx'])
// 	// console.log(JSON.stringify(arr))
// 	// //字符类型 ''
// 	// var arr = db.buildSql('update user set name = ?, age = ?', ['', 20])
// 	// console.log(JSON.stringify(arr))
// 	// //字符类型 null
// 	// var arr = db.buildSql('update user set name = ?, age = ?', [null, 20])
// 	// console.log(JSON.stringify(arr))
// 	// //字符类型 undefined
// 	// var arr = db.buildSql('update user set name = ?, age = ?', [undefined, 20])
// 	// console.log(JSON.stringify(arr))

// 	// //正常数据
// 	// var arr = db.buildSql('update user set name = ?, age = ?', ['wjx', 20])
// 	// console.log(JSON.stringify(arr))
// })